package biback.domain.product

import biback.domain._
import biback.domain.price.{BaseInt, IntKey, IntPrice}
import biback.utils.{GeneralAlgebra, MethodNoImplement}
import cats.Monad
import cats.data.NonEmptyList

trait ProductAlgebra[F[_]] {
  val product: ProductAlgebra.Service[F]
}

object ProductAlgebra {

  trait Service[F[_]] extends GeneralAlgebra[F] {
    def get(prdCode: ProductCode)(implicit F: Monad[F]): ErrOrF[Option[SaleableProduct]] =
      orF(Left(MethodNoImplement("get")))

    def getParam(product: BaseProduct)(implicit F: Monad[F]): ErrOrF[Option[ProductParam]] =
      orF(Left(MethodNoImplement("getParam")))

    def foundParam(product: BaseProduct)(implicit F: Monad[F]): ErrOrF[ProductParam] =
      foundF(getParam(product), ProductParamNotFound(product))

    def found(prdCode: ProductCode)(implicit F: Monad[F]): ErrOrF[SaleableProduct] =
      foundF(get(prdCode), ProductNotFound(prdCode))

    def listBaseInt(key: IntKey, from: TrnDate, to: TrnDate)(implicit F: Monad[F]): ErrOrF[NonEmptyList[BaseInt]] =
      orF(Left(MethodNoImplement("listBaseInt")))

    def foundIntPrice(prdCode: ProductCode)(implicit F: Monad[F]): ErrOrF[IntPrice] =
      orF(Left(MethodNoImplement("foundIntPrice")))
  }

}
